package org.example.c_0_003;

import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁（共享锁、排他锁）
 */
public class T_ReentrantReadWriteLock {
    private CountDownLatch countDownLatch = new CountDownLatch(20);
    private ReentrantLock reentrantLock = new ReentrantLock();
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    private Lock readLock = reentrantReadWriteLock.readLock();
    private Lock writeLock = reentrantReadWriteLock.writeLock();

    public void read() {
        readLock.lock();
        try {
            Thread.sleep(1000L);
            System.out.println("进行读操作");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            countDownLatch.countDown();
            readLock.unlock();
        }
    }

    public void write() {
        writeLock.lock();
        try {
            Thread.sleep(1000L);
            System.out.println("进行写操作");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            countDownLatch.countDown();
            writeLock.unlock();
        }
    }

    @Test
    public void test(){
        for (int i = 0; i < 18; i++) {
            new Thread(this::read).start();
        }
        for (int i = 0; i < 2; i++) {
            new Thread(this::write).start();
        }
        try {
            countDownLatch.await(20, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
